package com.example.mygame;

public class Round {
    ChessPiece[][] allChessPieces;
    private int operator;
    private int num_CAMP_RED;
    private int num_CAMP_BLUE;


    //-------------------------------------------------------------------------
    //开始游戏所需的重要操作
    /**
     * 构造回合
     * @param cps 棋子二维数组
     */
    public Round(ChessPiece[][] cps) {
        this.allChessPieces = cps;
        operator = ChessPiece.CAMP_RED;//当前操作员 默认红方先
        num_CAMP_RED = 1;
        num_CAMP_BLUE = 1;
    }

    /**
     * 设置操作员
     * @param operator 操作方的阵营
     */
    public void setOperator(int operator) {
        this.operator = operator;
    }
    //-------------------------------------------------------------------------
    //回合操作
    /**
     * 获取获胜者
     * @return 获胜者阵营，0代表尚未有一方获胜
     */
    public int GetWinner(){
        if(num_CAMP_RED == 0)   return ChessPiece.CAMP_BLUE;
        else if(num_CAMP_BLUE == 0) return ChessPiece.CAMP_RED;
        else return 0;
    }

    /**
     * 运行回合
     * 先检查是否相邻
     * 再区分主动被动方后检查是否同一阵营
     * 同一阵营只换位
     * 不同阵营交战完换位
     * 最后轮询一次倒计时并交换操作员
     * @param operate_cp_A 操作棋子A
     * @param operate_cp_B 操作棋子B
     * @return 是否成功运行回合，true代表运行成功
     */
    public boolean Run(ChessPiece operate_cp_A, ChessPiece operate_cp_B){
        //检查是否相邻
        if(!CheckIfBorder(operate_cp_A,operate_cp_B))    return false;

        //区分主动被动方
        ChessPiece cp_Active = null;//主动方棋子
        ChessPiece cp_Passive = null;//被动方棋子
        if(operator == operate_cp_A.getCamp()){
            cp_Active = operate_cp_A;
            cp_Passive = operate_cp_B;
        }
        else if(operator == operate_cp_B.getCamp()){
            cp_Active = operate_cp_B;
            cp_Passive = operate_cp_A;
        }
        else return false;


        //检查是否同一阵营
        if(isSameCamp(cp_Active,cp_Passive)){
            Swap(cp_Active,cp_Passive);
        }
        else{
            Warfare(cp_Active,cp_Passive);
            Swap(cp_Active,cp_Passive);
        }

        //轮询倒计时
        RoundPassAll(allChessPieces);
        //交换操作员
        SwitchOperator();
        return true;
    }
    //-------------------------------------------------------------------------
    //回合操作细节内容
    /**
     * 检查操作的两枚棋子是否相邻
     * @param cp_A 操作棋子A
     * @param cp_B 操作棋子B
     * @return 是否相邻，true代表相邻
     */
    public boolean CheckIfBorder(ChessPiece cp_A, ChessPiece cp_B){
        int deltaX = Math.abs(cp_A.getX()-cp_B.getX());
        int deltaY = Math.abs(cp_A.getY()-cp_B.getY());
        if(deltaX + deltaY == 1)    return true;
        return false;
    }

    /**
     * 比较两棋子是否为同一阵营
     * @param cp_A 棋子A
     * @param cp_B 棋子B
     * @return  是否为同一阵营
     */
    private boolean isSameCamp(ChessPiece cp_A,ChessPiece cp_B){
        if(cp_A.getCamp()==cp_B.getCamp())  return true;
        else return false;
    }

    /**
     * 交换两棋子除了位置以外全部数据
     * @param cp_A 棋子A
     * @param cp_B 棋子B
     */
    void Swap(ChessPiece cp_A,ChessPiece cp_B){
        ChessPiece temp  = new ChessPiece(cp_A);
        cp_A.setToValueOf(cp_B);
        cp_B.setToValueOf(temp);
        //由于全部交换了再把位置换回来
        cp_B.setToPositionOf(cp_A);
        cp_A.setToPositionOf(temp);
    }

    /**
     * 两棋子交战
     * 当前战力大的获胜
     * 相同战力主动方获胜
     * 败者被俘阵营更换为胜者阵营
     * @param cp_Active 主动方棋子
     * @param cp_Passive 被动方棋子
     */
    private void Warfare(ChessPiece cp_Active, ChessPiece cp_Passive){
        if(cp_Active.getPower_current()>=cp_Passive.getPower_current()){
            Capture(cp_Active,cp_Passive);
        }
        else{
            Capture(cp_Passive,cp_Active);
        }
        Hurt(cp_Active,cp_Passive);
        Tired(cp_Active);
        Tired(cp_Passive);
    }

    /**
     * 俘获
     * 迫使战败方转换阵营为战胜方
     * @param cp_Winner 战胜方棋子
     * @param cp_Loser 战败方棋子
     */
    void Capture(ChessPiece cp_Winner,ChessPiece cp_Loser){
        ChangeWinnerNum(cp_Winner);
        ChangeLoserNum(cp_Loser);

        cp_Loser.setCamp(cp_Winner.getCamp());
    }

    /**
     * 修正当前回合获胜者一方棋子数量
     * @param cp_Winner 获胜者棋子
     */
    void ChangeWinnerNum(ChessPiece cp_Winner){
        if(cp_Winner.getCamp() == ChessPiece.CAMP_RED){
            num_CAMP_RED++;
        }
        else if(cp_Winner.getCamp() == ChessPiece.CAMP_BLUE){
            num_CAMP_BLUE++;
        }
    }

    /**
     * 修正当前回合失败者一方棋子数量
     * @param cp_Loser 失败者棋子
     */
    void ChangeLoserNum(ChessPiece cp_Loser){
        if(cp_Loser.getCamp() == ChessPiece.CAMP_RED){
            num_CAMP_RED--;
        }
        else if(cp_Loser.getCamp() == ChessPiece.CAMP_BLUE){
            num_CAMP_BLUE--;
        }
    }

    /**
     * 伤害
     * 使得互相减少当前战力
     * @param cp_Active 主动方棋子
     * @param cp_Passive 被动方棋子
     */
    void Hurt(ChessPiece cp_Active, ChessPiece cp_Passive)
    {
        int current_Active =  cp_Active.getPower_current()-cp_Passive.getPower_current();
        int current_Passive = cp_Passive.getPower_current()-cp_Active.getPower_current();
        current_Active= Math.max(current_Active, 0);
        current_Passive= Math.max(current_Passive, 0);
        cp_Active.setPower_current(current_Active);
        cp_Passive.setPower_current(current_Passive);
    }

    /**
     * 战损
     * 刷新战损恢复倒计时2回合
     * @param cp 棋子
     */
    void Tired(ChessPiece cp){
        cp.setCountdown(4);
    }

    /**
     * 回合结算全部
     * @param cps 棋子二维数组
     */
    void RoundPassAll(ChessPiece[][] cps){
        for (int i = 0; i < cps.length; i++) {
            for (int j = 0; j < cps[i].length; j++) {
                RoundPass(cps[i][j]);
            }
        }
    }

    /**
     * 回合结算
     * @param cp 棋子
     */
    void RoundPass(ChessPiece cp){
        StartCountDown(cp);
        int currentCD = cp.getCountdown();
        if(currentCD > 0)  return;
        else if(currentCD==0) {
            RecoverPowerCurrent(cp);
            currentCD=0;
        }
        else    currentCD = -1;
        cp.setCountdown(currentCD);
    }

    /**
     * 战损恢复倒计时推移一回合
     * @param cp 棋子
     */
    void StartCountDown(ChessPiece cp)
    {
        if(cp.getCountdown()>0)
        cp.setCountdown(cp.getCountdown()-1);
    }


    /**
     * 恢复当前战力到原始战力
     * @param cp 棋子
     */
    void RecoverPowerCurrent(ChessPiece cp){
        cp.setPower_current(cp.getPower_original());;
    }

    /**
     * 交换操作员
     */
    public void SwitchOperator(){
        if(operator == ChessPiece.CAMP_RED) operator = ChessPiece.CAMP_BLUE;
        else if(operator == ChessPiece.CAMP_BLUE)   operator = ChessPiece.CAMP_RED;
    }

    //-------------------------------------------------------------------------
    //批量设置
    /**
     * 清除所有战损恢复倒计时
     */
    public void ClearAllCountDown(){
        for (int i = 0; i < allChessPieces.length; i++) {
            for (int j = 0; j < allChessPieces[0].length; j++) {
                allChessPieces[i][j].setCountdown(-1);
            }
        }
    }

    /**
     * 批量设置阵营
     * @param camps 阵营二维数组
     */
    public void SetAllCamp(int[][] camps){
        for (int i = 0; i < camps.length; i++) {
            for (int j = 0; j < camps[0].length; j++) {
                allChessPieces[i][j].setCamp(camps[i][j]);
            }
        }
    }

    /**
     * 批量设置原始战力(会同时设置全部当前战力)
     * @param poweroriginals 原始战力二维数组
     */
    public void SetAllPowerOriginal(int[][] poweroriginals){
        for (int i = 0; i < poweroriginals.length; i++) {
            for (int j = 0; j < poweroriginals[0].length; j++) {
                allChessPieces[i][j].setPower_original(poweroriginals[i][j]);
                allChessPieces[i][j].setPower_current(poweroriginals[i][j]);
            }
        }
    }


    //-------------------------------------------------------------------------
    //批量获取
    /**
     * 获取所有阵营
     * @return 所有棋子的阵营二维数组
     */
    public int[][] GetAllCamp(){
        int[][] camps = new int[allChessPieces.length][allChessPieces[0].length];
        for (int i = 0; i < camps.length; i++) {
            for (int j = 0; j < camps[0].length; j++) {
                camps[i][j] = allChessPieces[i][j].getCamp();
            }
        }
        return camps;
    }

    /**
     * 获取所有当前战力
     * @return 所有棋子的当前战力
     */
    public int[][] GetAllPower_current(){
        int[][] power_currents = new int[allChessPieces.length][allChessPieces[0].length];
        for (int i = 0; i < power_currents.length; i++) {
            for (int j = 0; j < power_currents[0].length; j++) {
                power_currents[i][j] = allChessPieces[i][j].getPower_current();
            }
        }
        return power_currents;
    }

    /**
     * 获取所有原始战力
     * @return 所有棋子的原始战力
     */
    public int[][] GetAllPower_original(){
        int[][] power_originals = new int[allChessPieces.length][allChessPieces[0].length];
        for (int i = 0; i < power_originals.length; i++) {
            for (int j = 0; j < power_originals[0].length; j++) {
                power_originals[i][j] = allChessPieces[i][j].getPower_original();
            }
        }
        return power_originals;
    }
}
